package com.example.springboot.service;

import cn.hutool.json.JSONUtil;
import com.example.springboot.dto.MerchantRentalDTO;
import com.example.springboot.entity.ClothingRental;
import com.example.springboot.entity.Merchant;
import com.example.springboot.mapper.ClothingRentalMapper;
import com.example.springboot.mapper.MerchantMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ClothingRentalService {
    private static final Logger logger = LoggerFactory.getLogger(ClothingRentalService.class);

    @Autowired
    private OSSService ossService;

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private ClothingRentalMapper clothingRentalMapper;

    // 商家获取租赁数据
    public MerchantRentalDTO getMerchantRentals(Integer merchantId) {
        Merchant merchant = merchantMapper.findById(merchantId);
        List<ClothingRental> clothingRentals = clothingRentalMapper.findByMerchantId(merchantId);

        MerchantRentalDTO dto = new MerchantRentalDTO();
        dto.setMerchant(merchant);
        dto.setClothingRentals(clothingRentals);

        return dto;
    }

    // 商家更新状态
    public boolean updateRentalStatus(Integer rentalId, Integer status) {
        int updatedRows = clothingRentalMapper.updateStatus(rentalId, status);
        return updatedRows > 0;
    }

    // 商家新增衣物
    public boolean addNewRental(Integer merchantId, String setName, String topName, String pantsName, String skirtName,
                                String shoesName, String accessoryName, Double pricePerHour, MultipartFile imageFile,
                                Integer quantity, String size) throws Exception {
        int filledCount = 0;
        if (setName != null) filledCount++;
        if (topName != null) filledCount++;
        if (pantsName != null) filledCount++;
        if (skirtName != null) filledCount++;
        if (shoesName != null) filledCount++;
        if (accessoryName != null) filledCount++;

        if (filledCount != 1) {
            throw new IllegalArgumentException("只能选择一种衣物类型填写");
        }

        String imageUrl = ossService.uploadImage(imageFile);

        ClothingRental rental = new ClothingRental();
        rental.setMerchantId(merchantId);
        rental.setSetName(setName);
        rental.setTopName(topName);
        rental.setPantsName(pantsName);
        rental.setSkirtName(skirtName);
        rental.setShoesName(shoesName);
        rental.setAccessoryName(accessoryName);
        rental.setPricePerHour(BigDecimal.valueOf(pricePerHour));
        rental.setImageUrl(imageUrl);
        rental.setQuantity(quantity);
        rental.setSize(size);
        rental.setStatus(2); // 默认上架中
        rental.setCreatedAt(Timestamp.valueOf(LocalDateTime.now()));
        rental.setUpdatedAt(Timestamp.valueOf(LocalDateTime.now()));

        logger.info("Adding new rental: {}", JSONUtil.toJsonStr(rental));
        int insertedRows = clothingRentalMapper.insertClothingRental(rental);
        return insertedRows > 0;
    }

    // 商家更新库存
    public boolean updateRentalQuantity(Integer rentalId, Integer quantity) {
        if (quantity == null || quantity < 0) {
            throw new IllegalArgumentException("数量必须为非负整数");
        }
        int updatedRows = clothingRentalMapper.updateQuantity(rentalId, quantity);
        return updatedRows > 0;
    }

    // 管理员获取衣物列表
    public Map<String, Object> getAdminRentals(int page, int size, String role, String username, Integer status) {
        String decodedUsername = decodeUsername(username);
        validateInput(role, decodedUsername);

        int offset = (page - 1) * size;
        if (offset < 0) {
            logger.warn("Invalid page number: {}, setting offset to 0", page);
            offset = 0;
        }
        if (size <= 0) {
            logger.warn("Invalid size: {}, defaulting to 10", size);
            size = 10;
        }

        logger.info("Fetching rentals for role: {}, username: {}, page: {}, size: {}, status: {}",
                role, decodedUsername, page, size, status);

        try {
            String adminRole = clothingRentalMapper.findAdminRoleByUsername(decodedUsername);
            if (adminRole == null) {
                logger.error("No role found for username: {}", decodedUsername);
                throw new IllegalArgumentException("管理员用户不存在或角色未定义");
            }

            List<ClothingRental> rentals;
            int total;
            if ("super".equals(adminRole)) {
                logger.info("Super admin access: retrieving all rentals");
                rentals = clothingRentalMapper.findAll(offset, size, status);
                total = clothingRentalMapper.getTotalRentals(status);
            } else {
                Integer adminId = getAdminId(decodedUsername);
                logger.info("Common admin access: retrieving rentals for adminId: {}", adminId);
                rentals = clothingRentalMapper.findByAdminId(offset, size, adminId, status);
                total = clothingRentalMapper.getTotalRentalsByAdminId(adminId, status);
            }

            logger.info("Retrieved {} rentals, total count: {}", rentals.size(), total);

            Map<String, Object> response = new HashMap<>();
            response.put("data", rentals);
            response.put("total", total);
            return response;
        } catch (Exception e) {
            logger.error("Failed to fetch rentals for username: {}", decodedUsername, e);
            throw new RuntimeException("获取衣物列表失败: " + e.getMessage());
        }
    }

    // 管理员确认上架状态
    public boolean adminUpdateStatus(Integer rentalId, Integer status, String role, String username) {
        String decodedUsername = decodeUsername(username);
        validateInput(role, decodedUsername);

        ClothingRental rental = clothingRentalMapper.findById(String.valueOf(rentalId));
        if (rental == null) {
            logger.warn("Rental not found for rentalId: {}", rentalId);
            throw new IllegalArgumentException("衣物不存在");
        }

        String adminRole = clothingRentalMapper.findAdminRoleByUsername(decodedUsername);
        if ("common".equals(adminRole)) {
            Integer adminId = getAdminId(decodedUsername);
            if (!clothingRentalMapper.isRentalManagedByAdmin(rentalId, adminId)) {
                logger.warn("Permission denied for username: {} to update rentalId: {}", decodedUsername, rentalId);
                throw new IllegalArgumentException("无权限操作此衣物");
            }
        }

        int updatedRows = clothingRentalMapper.updateStatus(rentalId, status);
        logger.info("Updated rental status for rentalId: {}, new status: {}, rows affected: {}", rentalId, status, updatedRows);
        return updatedRows > 0;
    }

    // 管理员更新衣物信息
    public boolean adminUpdateRental(ClothingRental rental, String role, String username) {
        String decodedUsername = decodeUsername(username);
        validateInput(role, decodedUsername);

        ClothingRental existingRental = clothingRentalMapper.findById(String.valueOf(rental.getRentalId()));
        if (existingRental == null) {
            logger.warn("Rental not found for rentalId: {}", rental.getRentalId());
            throw new IllegalArgumentException("衣物不存在");
        }

        String adminRole = clothingRentalMapper.findAdminRoleByUsername(decodedUsername);
        if ("common".equals(adminRole)) {
            Integer adminId = getAdminId(decodedUsername);
            if (!clothingRentalMapper.isRentalManagedByAdmin(rental.getRentalId(), adminId)) {
                logger.warn("Permission denied for username: {} to update rentalId: {}", decodedUsername, rental.getRentalId());
                throw new IllegalArgumentException("无权限操作此衣物");
            }
        }

        rental.setUpdatedAt(Timestamp.valueOf(LocalDateTime.now()));
        int updatedRows = clothingRentalMapper.updateClothingRental(rental);
        logger.info("Updated rental for rentalId: {}, rows affected: {}", rental.getRentalId(), updatedRows);
        return updatedRows > 0;
    }

    // 管理员删除衣物
    public boolean adminDeleteRental(Integer rentalId, String role, String username) {
        String decodedUsername = decodeUsername(username);
        validateInput(role, decodedUsername);

        ClothingRental rental = clothingRentalMapper.findById(String.valueOf(rentalId));
        if (rental == null) {
            logger.warn("Rental not found for rentalId: {}", rentalId);
            throw new IllegalArgumentException("衣物不存在");
        }

        String adminRole = clothingRentalMapper.findAdminRoleByUsername(decodedUsername);
        if ("common".equals(adminRole)) {
            Integer adminId = getAdminId(decodedUsername);
            if (!clothingRentalMapper.isRentalManagedByAdmin(rentalId, adminId)) {
                logger.warn("Permission denied for username: {} to delete rentalId: {}", decodedUsername, rentalId);
                throw new IllegalArgumentException("无权限删除此衣物");
            }
        }

        int deletedRows = clothingRentalMapper.deleteById(rentalId);
        logger.info("Deleted rental for rentalId: {}, rows affected: {}", rentalId, deletedRows);
        return deletedRows > 0;
    }

    private void validateInput(String role, String username) {
        if (username == null || username.trim().isEmpty()) {
            logger.error("Username is null or empty");
            throw new IllegalArgumentException("Username header is required");
        }
        if (role == null || role.trim().isEmpty()) {
            logger.error("Role is null or empty");
            throw new IllegalArgumentException("Role header is required");
        }
    }

    private Integer getAdminId(String username) {
        Integer adminId = clothingRentalMapper.findAdminIdByUsername(username);
        if (adminId == null) {
            logger.error("No admin ID found for username: {}", username);
            throw new IllegalArgumentException("无法获取管理员 ID，用户名可能不存在");
        }
        return adminId;
    }

    private String decodeUsername(String username) {
        if (username == null) {
            return null;
        }
        try {
            return URLDecoder.decode(username, "UTF-8");
        } catch (Exception e) {
            logger.warn("Failed to decode username: {}, using original value", username, e);
            return username;
        }
    }
}